package com.axx.android.home.fragment;


import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.text.TextUtils;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.utils.SpatialRelationUtil;
import com.amap.api.maps.utils.overlay.SmoothMoveMarker;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.axx.android.LetterApp;
import com.axx.android.R;
import com.axx.android.base.BaseLazyFragment;
import com.axx.android.common.BaseModel;
import com.axx.android.common.Constants;
import com.axx.android.home.model.HomeLetter;
import com.axx.android.home.model.User;
import com.axx.android.letter.activity.LetterDetailActivity;
import com.axx.android.letter.activity.RecipientActivity;
import com.axx.android.profile.auth.model.AuthUser;
import com.axx.android.utils.ContextUtils;
import com.axx.android.utils.GsonUtils;
import com.axx.android.utils.HttpUtils;
import com.axx.android.utils.ImageLoader;
import com.axx.android.utils.ImageUtils;
import com.axx.android.utils.MapUtils;
import com.axx.android.utils.ViewUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.google.gson.reflect.TypeToken;
import com.igexin.sdk.PushManager;
import com.lzy.okgo.OkGo;
import com.sendtion.xrichtext.StringUtils;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;

import static java.lang.System.load;

/**
 * A simple {@link Fragment} subclass.
 */
public class MapFragment extends BaseLazyFragment implements AMap.OnMarkerClickListener, AMapLocationListener, AMap.OnCameraChangeListener, AMap.OnMapClickListener {


    @Bind(R.id.map)
    MapView mMapView;
    @Bind(R.id.tv_query)
    ImageView tvQuery;
    @Bind(R.id.iv_center)
    ImageView ivCenter;
    @Bind(R.id.iv_header)
    ImageView ivHeader;
    @Bind(R.id.tv_username)
    TextView tvUsername;
    @Bind(R.id.tv_distance)
    TextView tvDistance;
    @Bind(R.id.layout_user_window)
    LinearLayout layoutUserWindow;
    @Bind(R.id.layout_letter_window)
    LinearLayout layoutLetterWindow;
    @Bind(R.id.iv_from)
    ImageView ivFrom;
    @Bind(R.id.tv_from)
    TextView tvFrom;
    @Bind(R.id.tv_no)
    TextView tvNo;
    @Bind(R.id.iv_to)
    ImageView ivTo;
    @Bind(R.id.tv_to)
    TextView tvTo;
    @Bind(R.id.tv_content)
    TextView tvContent;
    @Bind(R.id.tv_num)
    TextView tvNum;
    @Bind(R.id.view_sex)
    View viewSex;
    @Bind(R.id.iv_location)
    ImageView ivLocation;
    @Bind(R.id.iv_refresh)
    ImageView ivRefresh;
    @Bind(R.id.location)
    TextView location;
    private AMap aMap;
    private AMapLocationClient mlocationClient;
    public AMapLocationClientOption mLocationOption = null;
    private List<User.UserListBean> userList;

    private User.UserListBean curUser;
    private List<HomeLetter.LetterListBean> letterList;
    private HomeLetter.LetterListBean curLetter;
    private LatLng lastCenter;

    public MapFragment() {
        // Required empty public constructor
    }


    /**
     * 初始化地图，将当前位置显示到地图上
     */
    private void initLocation() {
        aMap = mMapView.getMap();
        aMap.setOnMarkerClickListener(this);
        aMap.setOnCameraChangeListener(this);
        aMap.getUiSettings().setZoomControlsEnabled(false);
        aMap.setOnMapClickListener(this);

        mlocationClient = new AMapLocationClient(getContext());
        mLocationOption = new AMapLocationClientOption();
        mlocationClient.setLocationListener(this);
        mLocationOption.setOnceLocation(true);
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        mlocationClient.setLocationOption(mLocationOption);
        mlocationClient.startLocation();
    }

    public static MapFragment newInstance() {
        Bundle args = new Bundle();

        MapFragment fragment = new MapFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.unbind(this);
        if (mMapView != null) {
            mMapView.onDestroy();
        }
    }


    /**
     * @param latitude  精度
     * @param longitude 维度
     *                  <p>
     * @param b
     */
    private void fetchUserPoint(double latitude, double longitude, boolean isQuery) {
        renderMeMarker(LetterApp.curLocation);
        Map<String, String> string = new HashMap<>();
        string.put("nowpage", "1");
        string.put("pagenum", "15");

        string.put("userLongitude", String.valueOf(LetterApp.curLocation.getLongitude()));
        string.put("userLatitude", String.valueOf(LetterApp.curLocation.getLatitude()));

        if (isQuery) {
            string.put("longitude", String.valueOf(longitude));
            string.put("latitude", String.valueOf(latitude));
        } else {
            string.put("longitude", String.valueOf(LetterApp.curLocation.getLongitude()));
            string.put("latitude", String.valueOf(LetterApp.curLocation.getLatitude()));
        }

        HttpUtils.post(Constants.Url.User.USER_RECENT_POINT, string, new HttpUtils.SJCallBack() {
            @Override
            public void onSuccess(String result) {
                try {
                    BaseModel<User> userBaseModel = GsonUtils.fromJson(result, new TypeToken<BaseModel<User>>() {
                    });
                    if (userBaseModel.isSuccess()) {
                        handleUserResult(userBaseModel.data);
                    } else {
                        showToast(userBaseModel.message);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    showErrorParse();
                }
            }

            @Override
            public void onError() {
                showErrorNet();
            }
        });
    }

    /**
     * @param data 添加用户marker
     */
    private void handleUserResult(User data) {
        if (data.getUserList().size() != 0) {
            tvQuery.setBackgroundResource(R.drawable.ic_map_query_complete);
            handleAddUserMarker(data.getUserList());
        }
        if (data.getUserList().size() == 0) {
            tvQuery.setBackgroundResource(R.drawable.ic_map_empty_user);
        }
    }

    /**
     * @param userList 将用户信息显示到地图上
     */
    private void handleAddUserMarker(List<User.UserListBean> userList) {
        this.userList = userList;
        for (final User.UserListBean userListBean : userList) {
            if (userListBean.getDistance() != 0) {
                HttpUtils.getBitmap(userListBean.getHeadPic(), 24, new HttpUtils.SJBitmapCallBack() {
                    @Override
                    public void onSuccess(Bitmap bitmap) {
                        MarkerOptions markerOption = new MarkerOptions();
                        markerOption.position(new LatLng(userListBean.getLatitude(), userListBean.getLongitude()));
                        markerOption.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
                        markerOption.snippet("1" + ":" + userListBean.getId());
                        aMap.addMarker(markerOption);
                    }
                });

            }
        }
    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        String datas = marker.getSnippet();
        String array[] = datas.split(":");
        if (array.length != 0) {
            if ("1".equals(array[0])) {
                showUserWindow(array[1]);
            } else {
                showLetterWindow(array[1]);
            }
        }
        return true;
    }

    private void showLetterWindow(String s) {
        if (layoutUserWindow.getVisibility() == View.VISIBLE) {
            layoutUserWindow.setVisibility(View.GONE);
        }
        if (layoutLetterWindow.getVisibility() == View.GONE) {
            layoutLetterWindow.setVisibility(View.VISIBLE);
        }
        curLetter = null;
        for (HomeLetter.LetterListBean letterListBean : letterList) {
            String id = String.valueOf(letterListBean.getId());
            if (id.equals(s)) {
                curLetter = letterListBean;
                break;
            }
        }
        moveLocationImage(156);
        ivFrom.setTag(null);
        ivTo.setTag(null);
        tvNo.setText("To " + curLetter.getMainId().getTrains() + "次");
        tvNum.setText(curLetter.getMainId().getCode());
        String title = curLetter.getMainId().getTitle();
        location.setText(curLetter.getMainId().getFromPlace() + "至" + curLetter.getMainId().getToPlace());

        int length = title.length() < 30 ? title.length() : 30;
        title = title.substring(0, length);
        if (length == 30) {
            title = "#" + title + "...#" + getContentSize();
        } else {
            title = "#" + title + "#" + getContentSize();
        }

        tvContent.setText(title);
        tvFrom.setText(curLetter.getMainId().getFromUser().getNickName());
        tvTo.setText(curLetter.getMainId().getToUser().getNickName());
        ImageLoader.loadRoundImage(curLetter.getMainId().getFromUser().getHeadPic(), ivFrom, getContext());
        ImageLoader.loadRoundImage(curLetter.getMainId().getToUser().getHeadPic(), ivTo, getContext());

        ivTo.setTag("to");
        ivFrom.setTag("from");
        //ivTo.setOnClickListener(headerClick);
        //ivFrom.setOnClickListener(headerClick);

    }

    private View.OnClickListener headerClick = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String userString;
            if (view.getTag().toString().equals("to")) {
                userString = GsonUtils.toJson(curLetter.getMainId().getToUser());

            } else {
                userString = GsonUtils.toJson(curLetter.getMainId().getFromUser());
            }
            try {
                User.UserListBean userListBean1 = GsonUtils.fromJson(userString, new TypeToken<User.UserListBean>() {
                });
                Intent intent = new Intent(getActivity(), RecipientActivity.class);
                intent.putExtra("model", userListBean1);
                startActivity(intent);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    };


    private void showUserWindow(String s) {
        for (User.UserListBean userListBean : userList) {
            if (s.equals(userListBean.getId())) {
                curUser = userListBean;
                break;
            }
        }
        moveLocationImage(64);
        if (layoutLetterWindow.getVisibility() == View.VISIBLE) {
            layoutLetterWindow.setVisibility(View.GONE);
        }
        if (layoutUserWindow.getVisibility() == View.GONE) {
            layoutUserWindow.setVisibility(View.VISIBLE);
        }
        if (curUser.getSex().equals("M")) {
            viewSex.setBackgroundResource(R.drawable.ic_sex_man);
        } else {
            viewSex.setBackgroundResource(R.drawable.ic_sex_woman);
        }
        tvUsername.setText(curUser.getNickName());
        tvDistance.setText(curUser.getDistance() + "km");
        ImageLoader.loadRoundImage(curUser.getHeadPic(), ivHeader, getContext());
    }

    private void moveLocationImage(int size) {
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) ivLocation.getLayoutParams();
        layoutParams.setMargins(0, 0, 0, ViewUtils.dip2px(getContext(), size));
        ivLocation.setLayoutParams(layoutParams);
    }


    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        tvQuery.setBackgroundResource(R.drawable.ic_map_loction_complete);
        aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude())));
        if (aMapLocation != null) {
            LetterApp.curLocation = aMapLocation;
            setCenterPoint();
            fetchUpdateUserInfo();
            fetchUserPoint(aMapLocation.getLatitude(), aMapLocation.getLongitude(), false);
            fetchLetterPoint(aMapLocation.getLatitude(), aMapLocation.getLongitude(), MapUtils.getCity(LetterApp.curLocation.getAdCode()));
        }
    }

    private String getContentSize() {
        int size = 0;
        List<String> textList = StringUtils.cutStringByImgTag(curLetter.getMainId().getText());
        for (String text : textList) {
            if (!text.contains("<img") && !text.contains("src=")) {
                text = text.trim();
                size = size + text.length();
            }
        }
        return size == 0 ? "" : size + "字";
    }

    private void fetchUpdateUserInfo() {
        if (LetterApp.authUser == null)
            return;
        Map<String, String> map = new HashMap<>();
        map.put("phone", LetterApp.authUser.getPhone());
        map.put("psw", LetterApp.authUser.getPassword());
        map.put("loginType", "1");
        map.put("loginLongitude", LetterApp.curLocation.getLongitude() + "");
        map.put("loginLatitude", LetterApp.curLocation.getLatitude() + "");
        map.put("cityCode", MapUtils.getCity(LetterApp.curLocation.getAdCode()));
        map.put("cityName", LetterApp.curLocation.getCity());


        HttpUtils.post(Constants.Url.User.USER_LOGIN, map, new HttpUtils.SJCallBack() {
            @Override
            public void onSuccess(String result) {
                hideLoading();
                try {
                    BaseModel<AuthUser> authUserBaseModel = GsonUtils.fromJson(result, new TypeToken<BaseModel<AuthUser>>() {
                    });
                    if (authUserBaseModel.isSuccess()) {
                        String password = LetterApp.authUser.getPassword();
                        LetterApp.authUser = authUserBaseModel.data;
                        LetterApp.authUser.setPassword(password);
                        ContextUtils.saveUser(getActivity(), LetterApp.authUser);
                        //初始化推送
                        PushManager.getInstance().bindAlias(getActivity(), authUserBaseModel.data.getId());
                        PushManager.getInstance().turnOnPush(getActivity());
                    } else {
                        showToast(authUserBaseModel.message);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    showErrorParse();
                }
            }

            @Override
            public void onError() {
                hideLoading();
                showErrorNet();
            }
        });
    }

    private void setCenterPoint() {
        int[] location = new int[2];
        ivCenter.getLocationInWindow(location);
        int x = location[0];
        int y = location[1];
        lastCenter = aMap.getProjection().fromScreenLocation(new Point(x, y));
    }

    private void fetchLetterPoint(double latitude, double longitude, String city) {
        Map<String, String> data = new HashMap<>();
        data.put("latitude", latitude + "");
        data.put("longitude", longitude + "");
        data.put("city", city);

        HttpUtils.post(Constants.Url.Letter.LETTER_RECENT_POINT, data, new HttpUtils.SJCallBack() {
            @Override
            public void onSuccess(String result) {
                try {
                    BaseModel<HomeLetter> homeLetterBaseModel = GsonUtils.fromJson(result, new TypeToken<BaseModel<HomeLetter>>() {
                    });
                    if (homeLetterBaseModel.isSuccess()) {
                        handleAddLetterMarker(homeLetterBaseModel.data.getLetterList());
                    } else {
                        showToast(homeLetterBaseModel.message);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    showErrorParse();
                }

            }

            @Override
            public void onError() {
                showErrorNet();
            }
        });
    }

    private void handleAddLetterMarker(List<HomeLetter.LetterListBean> letterList) {
        if (letterList.size() == 0) {
            return;
        }
        showToast("发现" + letterList.size() + "封信");
        this.letterList = letterList;
        for (HomeLetter.LetterListBean letterListBean : letterList) {
            moveLetter(letterListBean);
        }
    }

    private void moveLetter(final HomeLetter.LetterListBean letterListBean) {
        if (TextUtils.isEmpty(letterListBean.getPointline()))
            return;
        HttpUtils.getBitmapV2(letterListBean.getMainId().getTools().getPic(), 24, new HttpUtils.SJBitmapCallBack() {
            @Override
            public void onSuccess(Bitmap bitmap) {
                List<LatLng> latLngList = new ArrayList<>();
                //把所有小节点找出来。添加工具移动的点中
                String[] points = letterListBean.getMainId().getPointLine().split(";");
                for (String point : points) {
                    String[] child = point.split(",");
                    latLngList.add(new LatLng(Double.valueOf(child[1]), Double.valueOf(child[0])));
                }

                //找出来信的当前位置。添加到起点位置
                latLngList.add(0, new LatLng(letterListBean.getLatitude(), letterListBean.getLongitude()));
                SmoothMoveMarker smoothMarker = new SmoothMoveMarker(aMap);
                smoothMarker.setDescriptor(BitmapDescriptorFactory.fromBitmap(bitmap));

                LatLng drivePoint = latLngList.get(0);
                Pair<Integer, LatLng> pair = SpatialRelationUtil.calShortestDistancePoint(latLngList, drivePoint);

                latLngList.set(pair.first, drivePoint);

                List<LatLng> subList = latLngList.subList(pair.first, latLngList.size());
                smoothMarker.setPoints(subList);
                smoothMarker.setTotalDuration(letterListBean.getMainId().getCostSecond());
                smoothMarker.startSmoothMove();
                smoothMarker.getMarker().setSnippet("2" + ":" + letterListBean.getId());
            }
        });
    }


    private void renderMeMarker(AMapLocation aMapLocation) {
        MarkerOptions markerOption = new MarkerOptions();
        markerOption.position(new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude()));
        markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                .decodeResource(getResources(), R.drawable.ic_me_marker)));
        markerOption.draggable(true);
        aMap.addMarker(markerOption);
    }


    @Override
    public void onCameraChange(CameraPosition cameraPosition) {

    }

    float initZoom;

    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
        if (initZoom == 0) {
            initZoom = cameraPosition.zoom;
            return;
        }
        if (cameraPosition.zoom != initZoom) {
            initZoom = cameraPosition.zoom;
            return;
        }

        int[] location = new int[2];
        ivCenter.getLocationInWindow(location);
        int x = location[0];
        int y = location[1];

        final LatLng nowCenter = aMap.getProjection().fromScreenLocation(new Point(x, y));
        float distance = AMapUtils.calculateLineDistance(nowCenter, lastCenter);
        if (distance < 500) {
            return;
        }
        long curTime = System.currentTimeMillis();
        if (curTime - lastDrogTime < 2000) {
            return;
        }
        lastDrogTime = curTime;
        lastCenter = nowCenter;
        tvQuery.setVisibility(View.VISIBLE);
        tvQuery.setBackgroundResource(R.drawable.ic_map_query);
        onMapClick(null);

        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                aMap.clear();
                EventBus.getDefault().post(nowCenter);
                fetchUserPoint(nowCenter.latitude, nowCenter.longitude, true);
                pointToCity(nowCenter);
            }
        }, 1500);


        //下载图片是异步的。下载完了图片会把图片缓存到。本地，

    }

    private long lastDrogTime = System.currentTimeMillis();

    private Handler handler = new Handler();

    private void pointToCity(final LatLng latLng) {
        LatLonPoint latLonPoint = new LatLonPoint(latLng.latitude, latLng.longitude);
        RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200, GeocodeSearch.AMAP);

        GeocodeSearch geocodeSearch = new GeocodeSearch(getContext());
        geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
                String code = regeocodeResult.getRegeocodeAddress().getAdCode();
                fetchLetterPoint(latLng.latitude, latLng.longitude, MapUtils.getCity(code));
            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

            }
        });
        geocodeSearch.getFromLocationAsyn(query);
    }


    @OnClick({R.id.layout_user_window, R.id.layout_letter_window, R.id.iv_refresh, R.id.iv_location})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.layout_user_window:
                Intent intent = new Intent(getContext(), RecipientActivity.class);
                intent.putExtra("model", curUser);
                startActivity(intent);
                break;
            case R.id.layout_letter_window:
                Intent intent1 = new Intent(getContext(), LetterDetailActivity.class);
                intent1.putExtra("from", "home");
                intent1.putExtra("id", curLetter.getMainIds());
                startActivity(intent1);
                break;
            case R.id.iv_location:
                onMapClick(null);
                tvQuery.setBackgroundResource(R.drawable.ic_map_locationing);
                mlocationClient.startLocation();
                break;
            case R.id.iv_refresh:
                long curTime = System.currentTimeMillis();
                if (curTime - lastDrogTime < 2000) {
                    return;
                }
                lastDrogTime = curTime;
                aMap.clear();
                onMapClick(null);
                fetchUserPoint(lastCenter.latitude, lastCenter.longitude, true);
                pointToCity(lastCenter);
                break;

        }
    }


    @Override
    public int getLayoutId() {
        return R.layout.fragment_map;
    }

    @Override
    public void init(Bundle savedInstanceState) {
        mMapView.onCreate(savedInstanceState);
        initLocation();
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // TODO: inflate a fragment view
        View rootView = super.onCreateView(inflater, container, savedInstanceState);
        ButterKnife.bind(this, rootView);
        return rootView;
    }

    @Override
    public void onMapClick(LatLng latLng) {
        layoutLetterWindow.setVisibility(View.GONE);
        layoutUserWindow.setVisibility(View.GONE);
        moveLocationImage(16);

    }
}
